package com.ssfGame.puremvc.model
{
	
	import com.game.utils.SwfManager;
	
	import com.adobe.serialization.json.JSON;
	import com.ssfGame.puremvc.StaticConst;
	import com.ssfGame.puremvc.model.vo.LoadVO;
	import com.ssfGame.puremvc.view.module.queueload.vo.QueueLoadVO;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	
	import org.puremvc.as3.patterns.proxy.Proxy;
	
	/**
	 * 
	 * @author chery
	 */
	public class LoadProxy extends Proxy
	{
		
		private var _loadDic:Dictionary;
		private var _currentIndex:uint=0;
		private var _currentQueueLoadState:String;
		private var _currentQueueLoadVO:QueueLoadVO;
		private var _loadedSwfList:Array=[];
		private var _isLoading:Boolean;
		
		private var _queueLoadVec:Vector.<QueueLoadVO>=new Vector.<QueueLoadVO>();
		/**
		 * 资源加载proxy
		 * @default 
		 */
		public static const NAME:String="LoadProxy";
		/**
		 * 
		 * @param proxyName
		 * @param data
		 */
		public function LoadProxy(proxyName:String=null, data:Object=null)
		{
			super(proxyName, data);
			_loadDic=new Dictionary();
		}

		public function get isLoading():Boolean
		{
			if(_isLoading==false&&_queueLoadVec.length==0){
				return false;
			}
			return true;
		}

		public function get currentQueueLoadVO():QueueLoadVO
		{
			return _currentQueueLoadVO;
		}

		public function addQueueLoad(_queueLoadVO:QueueLoadVO):void{
			
			var _vc:QueueLoadVO;
			if(_currentQueueLoadVO!=null){
				return;
			}
			if(!hasQueueLoadVO(_queueLoadVO)){
				_queueLoadVec.push(_queueLoadVO);
			}
			queueLoadStart();
		}
		private function queueLoadStart():void{
			if(!_currentQueueLoadVO){
				_currentQueueLoadVO=_queueLoadVec.shift();
				
				if(_currentQueueLoadVO){
					if(_currentQueueLoadVO.loadVec.length>0){
						_currentIndex=0;
						_currentQueueLoadState=StaticConst.V_SUCCESS;
						load(_currentQueueLoadVO.loadVec[_currentIndex]);
						_isLoading=true;
					}else{
						_currentQueueLoadState=StaticConst.V_FAILED;
					}
				}
			}
		}
		private function loadVOComplete(loadVO_Com:LoadVO):void{
			if(_currentQueueLoadVO){
				if(!_currentQueueLoadVO.isFullMode)//非完全加载模式
				{
					
				}else{
					if(loadVO_Com.state == StaticConst.V_SUCCESS)
					{
						//发出队列加载进度
						//加载成功，继续加载
						_currentIndex ++;
						if(_currentIndex == _currentQueueLoadVO.loadVec.length)
						{
							//加载结束
							queueLoadEnd();
						} else {
							//加载下一个
							load(_currentQueueLoadVO.loadVec[_currentIndex]);
						}
					} else if(loadVO_Com.state == StaticConst.V_FAILED){
						//队列加载状态
						_currentQueueLoadState = StaticConst.V_FAILED;
						//加载结束
						queueLoadEnd();
					}
				}
			}
		}
		private function queueLoadEnd():void{
			_isLoading=false;
			_currentQueueLoadVO.state=_currentQueueLoadState;
			if(_currentQueueLoadVO.callBakcFun!=null){
				_currentQueueLoadVO.callBakcFun(_currentQueueLoadVO);
			}
			_currentQueueLoadVO.gc();
			_currentQueueLoadVO=null;
			queueLoadStart();
		}
		/**
		 * 检索是否已有相同QueueLoadVO,ture：忽略队列加载 false: 队列加载
		 */		
		private function hasQueueLoadVO(queueLoadVO:QueueLoadVO):Boolean
		{
			var b:Boolean=false;
			for(var i:uint; i < _queueLoadVec.length; i++)
			{
				if(queueLoadVO == _queueLoadVec[i])
				{
					b = true;
					break;
				}
			}
			return b;
		}
		private function isSwfLoaded(str:String):Boolean{
			for(var i:uint=0;i<_loadedSwfList.length;i++){
				if(str==_loadedSwfList[i]){
					return true
				}
			}
			return false;
			
		}
		private function load(loadVO:LoadVO):void{
			
			if(loadVO.type==StaticConst.V_SWF&&isSwfLoaded(loadVO.url)){
				loadVO.state = StaticConst.V_SUCCESS;
				loadVO.progress=100;
				loadVOComplete(loadVO);
				return;
			}
		
			if(loadVO.type==StaticConst.V_IMG||loadVO.type==StaticConst.V_SWF){
				var _loader:Loader=new Loader();
				_loadDic[_loader]=loadVO;
				if(loadVO.domain == 2)
					_loader.load(new URLRequest(loadVO.url), new LoaderContext(true, ApplicationDomain.currentDomain));
				else
					_loader.load(new URLRequest(loadVO.url));
				_loader.contentLoaderInfo.addEventListener(Event.OPEN,imgSwfOpen);
				_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,imgSwfProgress);
				_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,imgSwfError);
				_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,imgSwfComplete);
			}else if(loadVO.type==StaticConst.V_JSON){
				var urlLoader:URLLoader=new URLLoader();
				_loadDic[urlLoader]=loadVO;
				urlLoader.load(new URLRequest(loadVO.url));
				urlLoader.addEventListener(Event.OPEN,dataOpen);
				urlLoader.addEventListener(IOErrorEvent.IO_ERROR,dataError);
				urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,dataError);
				urlLoader.addEventListener(ProgressEvent.PROGRESS,dataProgress);
				urlLoader.addEventListener(Event.COMPLETE,dataComplete);
			}
		}
		private function imgSwfOpen(E:Event):void{
			var thisDicObj:Object=findImgSwfLoadVO(E);
			var _loader:Loader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			if(_loadVO)	{
				setOpenTimer(_loadVO);
			}
		}
		private function imgSwfProgress(E:ProgressEvent):void{
			var thisDicObj:Object=findImgSwfLoadVO(E);
			var _loader:Loader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			
			if(_loadVO)	{
				if(_loadVO.isSendLoadPro){
					_loadVO.progress=Math.floor(100*_loader.contentLoaderInfo.bytesLoaded/_loader.contentLoaderInfo.bytesTotal);
					_loadVO.speed=uploadSizeShow(_loader.contentLoaderInfo.bytesLoaded/((getTimer()-_loadVO.startTime)/1000))+"/S";
					sendNotification(StaticConst.N_M_QUEUE_LOAD_PROGRESS,_currentQueueLoadVO,String(_currentIndex));
				}
			}
		}
		private function imgSwfError(E:Event):void{
			var thisDicObj:Object=findImgSwfLoadVO(E);
			var _loader:Loader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			
			if(_loadVO){
				_loadVO.state=StaticConst.V_FAILED;
				myTrace(_loadVO);
				sendNotification(StaticConst.N_M_LOAD_ERROR);
				//清除
				remLoader(_loader);
				delete _loadDic[_loader];
			}else{
				Debug.getInstance()._trace(this,"加载失败");
			}
			
		}
		
		private function imgSwfComplete(E:Event):void{
			var thisDicObj:Object=findImgSwfLoadVO(E);
			var _loader:Loader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			if(_loadVO){
				if(_loadVO.type==StaticConst.V_IMG){
					if(_loader.content is Bitmap){
						_loadVO.bitmapData=(_loader.content as Bitmap).bitmapData.clone();
						(_loader.content as Bitmap).bitmapData.dispose();
						(_loader.content as Bitmap).bitmapData=null;
					}
					if(_loadVO.bitmapData){
						_loadVO.state=StaticConst.V_SUCCESS;
					}else{
						_loadVO.state=StaticConst.V_FAILED;
					}
				}else if(_loadVO.type==StaticConst.V_SWF){
					var loaderInfo:LoaderInfo=E.target as LoaderInfo;
					_loadVO.state = StaticConst.V_SUCCESS;
					SwfManager.getInstance().addApp(loaderInfo,_loadVO.url);
					_loadedSwfList.push(_loadVO.url);
					_loadVO.loaderInfo=loaderInfo;
				}
				if(_loadVO.isSendLoadPro)
				{
					_loadVO.progress=Math.floor(100*_loader.contentLoaderInfo.bytesLoaded/_loader.contentLoaderInfo.bytesTotal);
					_loadVO.speed = uploadSizeShow(_loader.contentLoaderInfo.bytesLoaded/((getTimer()-_loadVO.startTime)/1000)) + "/S";
				}
				if(_loadVO.state==StaticConst.V_SUCCESS){
					
					loadVOComplete(_loadVO);
				}
				//清除
				remLoader(_loader);
				delete _loadDic[_loader];
			}
		}
		/**
		 * 清除 Loader
		 */		
		private function remLoader(loader:Loader):void
		{
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, imgSwfError);
			loader.contentLoaderInfo.removeEventListener(Event.OPEN, imgSwfOpen);
			loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, imgSwfProgress);
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, imgSwfComplete);
			return;
			try {
				loader.close();
			} catch(error:Error){
			}
			try {
				loader.unload();
			} catch (error:Error){
			}
			try {
				loader.unloadAndStop();
			} catch (error:Error){
			}
		}
		private function dataError(E:Event):void{
			var thisDicObj:Object=findDataLoadVO(E)
			var _urlLoader:URLLoader=thisDicObj.loader
			var _loadVO:LoadVO=thisDicObj.loadVO
			
			if(_loadVO){
				_loadVO.state=StaticConst.V_FAILED;
				Debug.getInstance()._trace(_loadVO.url,"数据加载失败");
				myTrace(_loadVO);
				sendNotification(StaticConst.N_M_JSON_LOAD_ERROR);
				removeUrlLoader(_urlLoader);
				delete _loadDic[_urlLoader];
			}else{
				Debug.getInstance()._trace(this,"加载出错");
			}
		}
		private function dataOpen(E:Event):void{
			var thisDicObj:Object=findDataLoadVO(E);
			var _urlLoader:URLLoader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			if(_loadVO){
				setOpenTimer(_loadVO);
			}
		}
		
		private function dataProgress(E:ProgressEvent):void{
			var thisDicObj:Object=findDataLoadVO(E);
			var _urlLoader:URLLoader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			if(_loadVO){
				if(_loadVO.isSendLoadPro){
					_loadVO.progress=Math.floor(100*_urlLoader.bytesLoaded/_urlLoader.bytesTotal);
					_loadVO.speed=uploadSizeShow(_urlLoader.bytesLoaded/((getTimer()-_loadVO.startTime)/1000))+"/S";
					sendNotification(StaticConst.N_M_QUEUE_LOAD_PROGRESS,_currentQueueLoadVO,String(_currentIndex));
				}
				
			}
		}
		private function dataComplete(E:Event):void{
			var thisDicObj:Object=findDataLoadVO(E);
			var _urlLoader:URLLoader=thisDicObj.loader;
			var _loadVO:LoadVO=thisDicObj.loadVO;
			if(_loadVO){
				
				var thisObj:Object=JSON.decode(_urlLoader.data);
				if(thisObj.CODE==0){
					_loadVO.state=StaticConst.V_SUCCESS;
					_loadVO.data=thisObj.DATA;
					loadVOComplete(_loadVO);
				}else{
					Debug.getInstance()._trace(this,_loadVO.url,"CODE!=0");
					sendNotification(StaticConst.N_M_JSON_LOAD_ERROR,thisObj.DES);
				}
				removeUrlLoader(_urlLoader);
				delete _loadDic[_urlLoader];
				
			}
			
		}
		/**
		 * 清除urlLoader
		 * */
		private function removeUrlLoader(urlLoader:URLLoader):void{
			urlLoader.removeEventListener(Event.OPEN,dataOpen)
			urlLoader.removeEventListener(IOErrorEvent.IO_ERROR,dataError)
			urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,dataError)
			urlLoader.removeEventListener(ProgressEvent.PROGRESS,dataProgress)
			urlLoader.removeEventListener(Event.COMPLETE,dataComplete)
		}
		private function setOpenTimer(loadVO:LoadVO):void{
			loadVO.startTime=getTimer()
		}
		
		private function findImgSwfLoadVO(E:*):Object{
			var _loader:Loader
			var _loadVO:LoadVO
			for(var i:* in _loadDic){
				_loader=i as Loader
				if(!_loader) continue;
				_loadVO=_loadDic[i] as LoadVO
				if(_loader==E.currentTarget){
					
					break
				}
			}
			return {loader:_loader,loadVO:_loadVO}
		}
		private function findDataLoadVO(E:*):Object{
			var _urlLoader:URLLoader
			var _loadVO:LoadVO
			for(var i:* in _loadDic){
				_urlLoader=i as URLLoader
				if(!_urlLoader) continue;
				_loadVO=_loadDic[i] as LoadVO
				if(_urlLoader==E.currentTarget){
					
					break
				}
			}
			return {loader:_urlLoader,loadVO:_loadVO}
			
		}
		/**
		 * 上传大小(处理)显示,保留一位小数
		 */		
		private function uploadSizeShow(i:uint):String
		{
			var str:String;
			if (i >= 1000000000) {
				
				str = String(Math.round((i / 1024 / 1024 / 1024) * 10) / 10) + "G";
				
			} else if(i >= 1000000) {
				
				str = String(Math.round((i / 1024 / 1024) * 10) / 10) + "M";
				
			} else if(i >= 1000) {
				
				str = String(Math.round((i / 1024) * 10) / 10) + "KB";
				
			} else {//B
				str = String(i) +"B";
			}
			return str;
		}
		private function myTrace(loadVO:LoadVO):void
		{
			//Debug start
			if(loadVO.state == StaticConst.V_FAILED)
			{
				var str:String = "\n\""+ loadVO.url +"\" 加载状态：\n";
				str += "type = " + loadVO.type + ";\n";
				str += "url = " + loadVO.url + ";\n";
				str += "classNameArr = " + loadVO.classNameArr + ";\n";
				str += "isSendLoadPro = " + loadVO.isSendLoadPro + ";\n";
				str += "domain = " + loadVO.domain + ";\n";
				str += "state = " + loadVO.state + ";\n";
				str += "data = " + loadVO.data + ";\n";
				str += "bitmapData = " + loadVO.bitmapData + ";\n";
				str += "classArr = " + loadVO.classArr + ";\n";
				str += "startTime = " + loadVO.startTime + ";\n";
				str += "progress = " + loadVO.progress + ";\n";
				str += "speed = " + loadVO.speed + ";\n";
				Debug.getInstance()._trace(str);
			}
			//Debug end
		}
	}
}